/**
 * wifi_ap.c
 * 
 * 使用hostapd管理WiFi接入点的实现文件
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
#include <dirent.h>
#include "wifi_ap.h"

/**
 * 初始化WiFi AP配置为默认值
 */
wifi_ap_error_t wifi_ap_init_config(wifi_ap_config_t *config)
{
    if (config == NULL) {
        return WIFI_AP_ERROR_GENERAL;
    }

    memset(config, 0, sizeof(wifi_ap_config_t));

    // 设置默认值
    strcpy(config->interface, "wlan0");
    strcpy(config->ssid, "WiFi_AP");
    strcpy(config->password, "12345678"); // 默认密码(不安全，实际使用时应更改)
    strcpy(config->channel, "6");
    strcpy(config->hw_mode, "g");
    strcpy(config->ieee80211d, "1");
    strcpy(config->country_code, "CN");
    strcpy(config->ieee80211n, "1");
    strcpy(config->wmm_enabled, "1");
    strcpy(config->auth_algs, "1");
    strcpy(config->wpa, "2");
    strcpy(config->wpa_key_mgmt, "WPA-PSK");
    strcpy(config->wpa_pairwise, "CCMP");
    strcpy(config->rsn_pairwise, "CCMP");
    strcpy(config->macaddr_acl, "0");
    strcpy(config->ignore_broadcast_ssid, "0");
    strcpy(config->hostapd_path, "/usr/sbin/hostapd");
    strcpy(config->config_path, "/tmp/hostapd.conf");

    return WIFI_AP_SUCCESS;
}

/**
 * 检查文件是否存在
 */
int file_exists(const char *path)
{
    struct stat buffer;
    return (stat(path, &buffer) == 0);
}

/**
 * 创建hostapd配置文件
 */
wifi_ap_error_t wifi_ap_create_config_file(const wifi_ap_config_t *config)
{
    FILE *fp;

    if (config == NULL) {
        return WIFI_AP_ERROR_CONFIG;
    }

    // 检查hostapd是否存在
    if (!file_exists(config->hostapd_path)) {
        return WIFI_AP_ERROR_HOSTAPD_NOT_FOUND;
    }

    // 创建配置文件
    fp = fopen(config->config_path, "w");
    if (fp == NULL) {
        perror("Failed to create hostapd config file");
        return WIFI_AP_ERROR_CONFIG;
    }

    // 写入配置
    fprintf(fp, "interface=%s\n", config->interface);
    fprintf(fp, "ssid=%s\n", config->ssid);
    fprintf(fp, "channel=%s\n", config->channel);
    fprintf(fp, "hw_mode=%s\n", config->hw_mode);
    fprintf(fp, "ieee80211d=%s\n", config->ieee80211d);
    fprintf(fp, "country_code=%s\n", config->country_code);
    fprintf(fp, "ieee80211n=%s\n", config->ieee80211n);
    fprintf(fp, "wmm_enabled=%s\n", config->wmm_enabled);
    fprintf(fp, "auth_algs=%s\n", config->auth_algs);
    fprintf(fp, "wpa=%s\n", config->wpa);
    fprintf(fp, "wpa_key_mgmt=%s\n", config->wpa_key_mgmt);
    fprintf(fp, "wpa_pairwise=%s\n", config->wpa_pairwise);
    fprintf(fp, "rsn_pairwise=%s\n", config->rsn_pairwise);
    fprintf(fp, "macaddr_acl=%s\n", config->macaddr_acl);
    fprintf(fp, "ignore_broadcast_ssid=%s\n", config->ignore_broadcast_ssid);

    // 如果设置了密码，则添加
    if (strlen(config->password) >= 8) {
        fprintf(fp, "wpa_passphrase=%s\n", config->password);
    }

    fclose(fp);
    return WIFI_AP_SUCCESS;
}

/**
 * 执行系统命令并检查结果
 */
wifi_ap_error_t execute_command(const char *cmd, const char *error_msg)
{
    int ret = system(cmd);
    if (ret == -1) {
        perror(error_msg);
        return WIFI_AP_ERROR_PROCESS;
    } else if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0) {
        fprintf(stderr, "%s (exit code: %d)\n", error_msg, WEXITSTATUS(ret));
        return WIFI_AP_ERROR_PROCESS;
    }
    return WIFI_AP_SUCCESS;
}

/**
 * 启用WiFi接口
 */
wifi_ap_error_t wifi_ap_enable_interface(const char *interface)
{
    char cmd[256];
    wifi_ap_error_t ret;

    if (interface == NULL) {
        return WIFI_AP_ERROR_GENERAL;
    }

    // 检查接口是否存在
    sprintf(cmd, "ip link show %s", interface);
    ret = execute_command(cmd, "WiFi interface does not exist");
    if (ret != WIFI_AP_SUCCESS) {
        return WIFI_AP_ERROR_INTERFACE_DOWN;
    }

    // 启用接口
    sprintf(cmd, "ip link set %s up", interface);
    ret = execute_command(cmd, "Failed to enable WiFi interface");
    if (ret != WIFI_AP_SUCCESS) {
        return WIFI_AP_ERROR_INTERFACE_DOWN;
    }

    return WIFI_AP_SUCCESS;
}

/**
 * 设置WiFi接口IP地址
 */
wifi_ap_error_t wifi_ap_set_ip(const char *interface, const char *ip_addr, const char *netmask)
{
    char cmd[256];

    if (interface == NULL || ip_addr == NULL || netmask == NULL) {
        return WIFI_AP_ERROR_GENERAL;
    }

    // 设置IP地址
    sprintf(cmd, "ip addr add %s/%s dev %s", ip_addr, netmask, interface);
    if (execute_command(cmd, "Failed to set IP address") != WIFI_AP_SUCCESS) {
        return WIFI_AP_ERROR_IP_CONFIG;
    }

    return WIFI_AP_SUCCESS;
}

/**
 * 启动WiFi接入点
 */
wifi_ap_error_t wifi_ap_start(const wifi_ap_config_t *config, wifi_ap_state_t *state)
{
    // 移除未使用的变量
    int pid;
    wifi_ap_error_t ret;

    if (config == NULL || state == NULL) {
        return WIFI_AP_ERROR_GENERAL;
    }

    // 检查是否已经在运行
    if (state->running) {
        return WIFI_AP_ERROR_ALREADY_RUNNING;
    }

    // 启用WiFi接口
    ret = wifi_ap_enable_interface(config->interface);
    if (ret != WIFI_AP_SUCCESS) {
        return ret;
    }

    // 创建配置文件
    ret = wifi_ap_create_config_file(config);
    if (ret != WIFI_AP_SUCCESS) {
        return ret;
    }

    // 使用fork创建子进程来运行hostapd
    pid = fork();
    if (pid == -1) {
        perror("Failed to fork process");
        return WIFI_AP_ERROR_PROCESS;
    } else if (pid == 0) {
        // 子进程：执行hostapd
        execl(config->hostapd_path, config->hostapd_path, config->config_path, 
              "-B", (char *)NULL);
        
        // 如果execl返回，则表示失败
        perror("Failed to execute hostapd");
        exit(EXIT_FAILURE);
    }

    // 父进程：等待一段时间以确保hostapd成功启动
    sleep(2);

    // 检查进程是否在运行
    if (kill(pid, 0) == -1) {
        fprintf(stderr, "hostapd process failed to start\n");
        return WIFI_AP_ERROR_PROCESS;
    }

    // 更新状态
    state->running = 1;
    state->pid = pid;
    memcpy(&state->config, config, sizeof(wifi_ap_config_t));

    return WIFI_AP_SUCCESS;
}

/**
 * 停止WiFi接入点
 */
wifi_ap_error_t wifi_ap_stop(wifi_ap_state_t *state)
{
    // 移除未使用的变量
    int ret;

    if (state == NULL || !state->running) {
        return WIFI_AP_SUCCESS; // 已经停止或无效状态
    }

    // 发送终止信号
    if (kill(state->pid, SIGTERM) == -1) {
        if (errno == ESRCH) {
            // 进程不存在
            state->running = 0;
            return WIFI_AP_SUCCESS;
        }
        perror("Failed to send SIGTERM to hostapd");
        return WIFI_AP_ERROR_SIGNAL;
    }

    // 等待进程终止
    ret = waitpid(state->pid, NULL, WNOHANG);
    if (ret == 0) {
        // 进程没有立即终止，等待一段时间
        sleep(2);
        // 如果仍未终止，强制终止
        if (kill(state->pid, SIGKILL) == 0) {
            waitpid(state->pid, NULL, 0);
        }
    }

    // 清理状态
    state->running = 0;
    state->pid = 0;
    memset(&state->config, 0, sizeof(wifi_ap_config_t));

    return WIFI_AP_SUCCESS;
}

/**
 * 检查WiFi接入点状态
 */
wifi_ap_error_t wifi_ap_check_status(wifi_ap_state_t *state)
{
    if (state == NULL) {
        return WIFI_AP_ERROR_GENERAL;
    }

    // 如果状态显示运行中，检查进程是否真的在运行
    if (state->running) {
        if (kill(state->pid, 0) == -1) {
            if (errno == ESRCH) {
                // 进程不存在，但状态显示运行中，更新状态
                state->running = 0;
                state->pid = 0;
                return WIFI_AP_ERROR_PROCESS;
            }
            perror("Failed to check hostapd process");
            return WIFI_AP_ERROR_GENERAL;
        }
    }

    return WIFI_AP_SUCCESS;
}

/**
 * 获取错误信息描述
 */
const char *wifi_ap_get_error_string(wifi_ap_error_t error_code)
{
    switch (error_code) {
        case WIFI_AP_SUCCESS:
            return "Success";
        case WIFI_AP_ERROR_GENERAL:
            return "General error";
        case WIFI_AP_ERROR_CONFIG:
            return "Configuration error";
        case WIFI_AP_ERROR_HOSTAPD_NOT_FOUND:
            return "hostapd not found";
        case WIFI_AP_ERROR_INTERFACE_DOWN:
            return "WiFi interface error";
        case WIFI_AP_ERROR_IP_CONFIG:
            return "IP configuration error";
        case WIFI_AP_ERROR_PROCESS:
            return "Process error";
        case WIFI_AP_ERROR_SIGNAL:
            return "Signal error";
        case WIFI_AP_ERROR_PERMISSION:
            return "Permission denied";
        case WIFI_AP_ERROR_ALREADY_RUNNING:
            return "AP is already running";
        default:
            return "Unknown error";
    }
}

/**
 * 清理临时文件和资源
 */
wifi_ap_error_t wifi_ap_cleanup(const wifi_ap_config_t *config)
{
    if (config == NULL) {
        return WIFI_AP_ERROR_GENERAL;
    }

    // 删除配置文件
    if (file_exists(config->config_path)) {
        if (unlink(config->config_path) == -1) {
            perror("Failed to delete hostapd config file");
            return WIFI_AP_ERROR_GENERAL;
        }
    }

    return WIFI_AP_SUCCESS;
}